1. Field of the Invention
The present invention relates in general to the field of software monitoring and development and in particular to methods and systems which permit accurate measuring of time intervals during which external interrupts are inhibited. Still more particularly, the present invention relates to methods and systems for software monitoring and development which permit the measurement of time intervals during which external interrupts are inhibited without requiring specialized measurement hardware.
2. Description of the Prior Art
Virtually all modern computer systems must have the capability to response to external events in a fast and predictable manner. The most common method for responding to these external events is to present them as interrupts to the system. Most operating systems, however, sometimes block or disable external interrupts to protect the integrity of system data structures while these structures are being accessed or during state transitions. In addition, some applications can also inhibit interrupts to protect integrity of its data structures.
Consequently, interrupt-blocking intervals, i.e., periods during which the system cannot respond to external interrupts, do have a negative effect of the overall responsiveness of the system. Moreover, interrupt-blocking is also the main cause for large and unpredictable interrupt latency, which can be roughly defined as the amount of time it takes for the system to respond to external events.
On a typical computer, all external events, in the form of prioritized interrupts, are usually presented first to an interrupt controller. This interrupt controller has the responsibility to resolve the priority differences among simultaneous interrupts. The interrupt with the highest priority then proceeds to the processor. When the processor hardware detects an interrupt being directed at it, the processor hardware must first determine whether the interrupt may be serviced.
An interrupt may be serviced if the processor is not in a state where external interrupts are blocked and, if there is one interrupt level already active, the incoming interrupt level must have higher priority. Once these conditions are met, an interrupt vector table, i.e., the Interrupt Descriptor Table ("IDT") in the Intel 80386 microprocessors architecture, is searched for the entry of the incoming interrupt level. Intel 80386 and 80486 microprocessors are products of Intel Corporation. More information on the Intel 803865, 80486 microprocessors can be found in the 1486 Microprocessor Programmers Reference Manual from the Intel Corporation. This table entry contains a vector to some code, usually called the interrupt handler or interrupt manager, which is responsible for processing the interrupt. The current program status (registers, program counter, and other information), which represents the state of the processor at the time of the interrupt, is then saved in some data structure in memory, and a new program status is loaded into the processor hardware, causing the interrupt handler to begin execution.
Upon completion of execution by the handler, the processor may do one of the following: (1) switch back to the point at which it was interrupted by reloading the program status saved at the time of interrupt, (2) enter the scheduler to schedule the most eligible task in the system to execute, or (3) on some real-time systems, execute the user task that is defined as being "connected" to the interrupt. Assuming that the interrupt handler and the scheduler are highly optimized, the system, including the kernel and applications, must not block interrupts for any long period of time because doing so would adversely effect the ability of the system to respond to external interrupts.
Most processors have explicit instructions which are utilized to block and unblock interrupts in their instruction sets. The Intel 80386 and 80486 processors have the CLI (Clear Interrupt flag) and STI (Set Interrupt flag) instructions. When a interruptblocking instruction is executed, the processor will set an interrupt flag, usually stored in some system register in the processor, to block all external interrupts (with the possible exception of non-maskable interrupts). The processor hardware will continue to block interrupts until an unblock-interrupt instruction is executed, in which case the interrupt flag will be
Thus, an effective method to measure interrupt-blocking times must keep track of these instructions in the execution path. In addition, some processors also block external interrupts via indirect means, such as:
(1) Task switches: some processors, such as the Intel 80386/80486, load the system registers, including the interrupt flag, on task switches. In this case, if the interrupt flag is cleared after the system registers are loaded, the processor would inhibit external interrupts until this flag is set.
(2) Interrupt gates: some processors automatically disable further interrupts immediately after being interrupted. On the Intel 386/486 processors, external interrupts going through interrupt gates automatically clear the interrupt flag.
(3) Interrupt returns (from interrupt procedures): in many operating systems, the system registers are reloaded upon returning from the interrupt handlers or procedures. The reloading of the system registers normally include the interrupt flag, which has control over whether the processor disables interrupts or not in its new state. If the system registers are restored to its original state at the point of interrupt, the interrupt flag would be set, indicating that interrupts are enabled.
Thus, any effective method to measure interrupt-blocking times must not only be able to keep track of explicit instructions that block or unblock interrupts, but must also be able to detect all cases, e.g., task switches, interrupt gates, and interrupt returns, where the processor's interrupt state (flag) is altered. By keeping track of all instances where interrupts are disabled and enabled, calculating the time intervals during which external interrupts are blocked is possible. The longest interrupt-blocking intervals may be identified precisely, and software developers may then optimize the affected pieces of code to reduce the length of these intervals.
In developing operating systems and applications, developers often desire to measure the length of time during which external interrupts are blocked. These measurements are used to optimize the program being evaluated in terms of the ability of the system to respond to external interrupts.
Presently, there are various methods for measuring the blocking of external interrupts. One method is a sampling method wherein the system is sampled at the rate timer interrupts are generated. Most computer systems have at least one softwareprogrammable timer. The timer may be used to generate interrupts to the system at a predetermined rate. Normally, the timer is initialized with an integer count. When the timer counts down to zero, an interrupt will be generated, and if it is configured to have the highest priority among external interrupts, the interrupt controller will present this interrupt first to the processor in the case that there are other competing simultaneous interrupts exist. In the meantime, the timer continues to count negative.
Once the interrupt is presented to the processor and the processor is not in an interrupt-inhibit state, the current program status will be saved, and the processor will vector to some entry point inside a special device driver. This special device driver will then read the timer, and subtract the timer result from zero. The result of this subtraction will represent the time it takes for the system to respond to external (timer) interrupts. On the other hand, if the processor blocks interrupts when the timer interrupt arrives, the time interrupt would be held pending until the processor enables the interrupts again. Once interrupts are enabled, the special device driver will be entered, and the timer will be read. The value obtained in this case, after being subtracted from zero, will thus represent the sum of the hardware response in the interrupt-blocking time. After the driver finishes what it needs to do, it will initialize the timer, and the whole process will repeat again.
After many iterations, the smallest results obtained by the dummy driver would represent the hardware response only, i.e., no interrupt-blocking at all by the processor. The largest results, however, would represent both the hardware response and the interrupt-blocking time. Thus, the difference between the smallest and largest values can be attributed to the interrupt-blocking time.
In other known systems, interrupt timing is not done using the interval timer and a special device driver. Rather, interrupt timing is done by utilizing some external hardware consisting of a pulse generator and a timing device, but this approach is very similar in concept and is also sampling in nature.
This sampling approach contains several weaknesses: (1) it does not report the precise locations at which interrupts are blocked and unblocked; (2) it does not accurately measure interrupt-blocking times and can only approximate these times by looking at the largest and smallest values obtained; (3) because of its sampling nature, this approach does not measure all time intervals during which interrupts are blocked; and (4) the coverage of testing cannot be determined since this approach does not provide precise locations where interrupts are blocked and unblocked.
Another system for evaluating the performance of source code in terms of interrupt-blocking time involves putting so-called "hooks" into the system and application code. Special hooks may be incorporated into the operating system and/or application code to record all occurrences where interrupts are blocked and unblocked. In recording occurrences of blocking and unblocking, a monitoring system may be used in conjunction with specialized hardware which will time-stamp each instance of a hook being encountered.
Systems which utilize hooks also contain several weaknesses such as: (1) careful, time-consuming examination the operating system's code and/or application code is required to determine exactly where external interrupts are blocked or unblocked; (2) interrupt-blocking periods caused by indirect means, such as the processor automatically blocking interrupts immediately after being interrupted are not taken into account; (3) a large amount of hooks placed into numerous places throughout the operating system and/or application code is potentially required; and (4) a separate set of hooks for different versions of the operating system and/or application may be required, and thus, such systems are not very convenient for external customer usage.
In yet another known method, identification macros are utilized to measure the performance of source code in terms of interrupt-blocking time. In this method, a macro is provided for each type of instruction that might block interrupts. At run-time, these macros will identify and attach an identification number on each potential interrupt-blocking instruction. Based on this output, a post-processing tool may be utilized to identify the pairs of instructions that might cause interrupts to be blocked for a substantial amount of time. As a result, test cases may then be written to exercise all of these instruction pairs. This method, however, does not consider all the cases in which interrupts are blocked, e.g., during the services of external interrupts.
Therefore, it should be apparent that a need exists for a software monitoring and development system which permits accurate measurement of interrupt-blocking times in all cases which could cause a processor to inhibit external interrupts.